package test;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import org.apache.commons.lang.StringUtils;

import com.icss.productinsure.util.EncryptUtil;
import com.icss.productinsure.util.Md5Util;

public class TcpClient {
	public static final int PAD_RIGHT = 0;
	public static final int PAD_LEFT = 1;
	protected String encoding = "GBK";// 字符编码
	protected String headBeforeLength = "";// 长度头的内容前填充的串
	protected String headAfterLength = "";// 长度头的内容后面填充的串
	protected int lengthHeadSize = 0; // 长度报文头大小
	protected int lengthHeadPad = PAD_RIGHT;//
	protected String lengthHeadPadChar = " ";

	// 传入socket连接传入的host、port与待传输的报文内容(以字符串形式读入的xml文件)
	public String call(String host, int port, String requestXml) throws Exception {
		Socket socket = null;// 建立一个socket
		try {
			socket = new Socket(host, port);// 开启socket
			// send
			int length = requestXml.getBytes(encoding).length;// 获取xml报文体的长度
			String lengthHead = "" + length;// 将长度变成字符串形式
			if (PAD_RIGHT == lengthHeadPad) {
				lengthHead = StringUtils.rightPad(lengthHead, lengthHeadSize, lengthHeadPadChar);
			} else if (PAD_LEFT == lengthHeadPad) {
				lengthHead = StringUtils.leftPad(lengthHead, lengthHeadSize, lengthHeadPadChar);
			}
			OutputStream out = socket.getOutputStream();// 获取输出流
			out.write((headBeforeLength + lengthHead + headAfterLength).getBytes(encoding));
			out.write(requestXml.getBytes(encoding));
			out.flush();

			// receive
			InputStream in = socket.getInputStream();
			byte[] buf = new byte[160240];
			int headLength = headBeforeLength.length() + lengthHeadSize + headAfterLength.length();
			StringBuilder headBuilder = new StringBuilder();
			int unreadLength = headLength;
			while (unreadLength > 0) {
				int readLength = in.read(buf, 0, unreadLength);
				headBuilder.append(new String(buf, 0, readLength, encoding));
				unreadLength -= readLength;
			}
			lengthHead = headBuilder.substring(headBeforeLength.length(), headBeforeLength.length() + lengthHeadSize).trim();
			length = Integer.parseInt(lengthHead);
			StringBuilder bodyBuilder = new StringBuilder();
			unreadLength = length;
			while (unreadLength > 0) {
				int readLength = in.read(buf, 0, unreadLength);
				bodyBuilder.append(new String(buf, 0, readLength, encoding));
				unreadLength -= readLength;
			}
			String returnXml = bodyBuilder.toString();
			return returnXml;
		} catch (Exception e) {
			throw e;
		} finally {
			if (socket != null) {
				try {
					socket.close();
				} catch (IOException e) {
					throw e;
				}
			}
		}
	}

	public String call(String requestXml) throws Exception {
		String ip = "10.0.35.79";// esb服务地址
		int port = 6507;// 端口
		return this.call(ip, port, requestXml);
	}

	public static TcpClient getTcpClient(String transCode) {
		TcpClient client = new TcpClient();
		client.setEncoding("GBK");
		client.setHeadBeforeLength("");
		client.setHeadAfterLength(StringUtils.rightPad(transCode, 7) + "gs0007");
		client.setLengthHeadSize(6);
		client.setLengthHeadPad(TcpClient.PAD_RIGHT);
		client.setLengthHeadPadChar(" ");
		return client;
	}

	private String encodeSignData(String reqXml, String charset) throws Exception {
		String signData;
		try {
			signData = Md5Util.getMD5String(reqXml.getBytes(charset));
		} catch (UnsupportedEncodingException e) {
			throw e;
		}
		return signData;
	}
	
	public String getHeadBeforeLength() {
		return headBeforeLength;
	}

	public void setHeadBeforeLength(String headBeforeLength) {
		this.headBeforeLength = headBeforeLength;
	}

	public String getHeadAfterLength() {
		return headAfterLength;
	}

	public void setHeadAfterLength(String headAfterLength) {
		this.headAfterLength = headAfterLength;
	}

	public int getLengthHeadSize() {
		return lengthHeadSize;
	}

	public void setLengthHeadSize(int lengthHeadSize) {
		this.lengthHeadSize = lengthHeadSize;
	}

	public int getLengthHeadPad() {
		return lengthHeadPad;
	}

	public void setLengthHeadPad(int lengthHeadPad) {
		this.lengthHeadPad = lengthHeadPad;
	}

	public String getLengthHeadPadChar() {
		return lengthHeadPadChar;
	}

	public void setLengthHeadPadChar(String lengthHeadPadChar) {
		this.lengthHeadPadChar = lengthHeadPadChar;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}
}
